QuickOPC User's Guide and Reference
OPC UA Application Manifest
Features > Management and Administration > OPC UA Application Manifest
In This Topic

Introduction

The OPC UA application manifest contains the application registration information together with data related to PKI administration, such as paths to the certificate stores used.

The information contained in the OPC UA application manifest can roughly be divided into three areas:

One important piece of information is the subject name of the application instance certificate. The component uses the subject name to locate the instance certificate in the certificate store, and if it is not found, it attempts to create a new instance certificate, and store it with the subject name. The default subject name is created automatically, based on the description (title) of the application assembly, or (if the preceding yields a name that is too generic, such as ‘mscorlib’ in many hosted scenarios) from other sources of information, such as the executable’s FileVersionInfo, or a main module name.

The application URI can be specified explicitly, or (if left empty) the component will determine it automatically, using the ApplicationUriTemplateString Property. See OPC UA Application URI Derivation for the template syntax, and more details about how the application URI is determined.

If you want to use a specific subject name for your application instance certificate, set the EasyUAApplication.ApplicationParameters.ApplicationManifest.InstanceCertificateSubject Property accordingly.

If you leave the subject name empty, QuickOPC will determine the subject name automatically from other information available. For example, when any of the properties below is not empty, QuickOPC will include it in the subject name:

Other parameters that influence the application certificate creation are e.g. EasyUAApplication.ApplicationParameters.ApplicationManifest.ApplicationNameApplicationUriString, and ProductUriString Property.

Effective Application Manifest

The full OPC UA application manifest contains a considerable amount of information. On one hand, all this information is critical to proper functioning of the OPC UA application itself, and it the OPC UA ecosystem. On the other hand, it would be cumbersome having to fill it in in its entirety for each new application. For this reason, QuickOPC uses a process in which it automatically acquires the information needed in the OPC UA application manifest from various sources, and by combining the information in a prescribed way, it finally determines the effective application manifest, which is the OPC UA application manifest that will actually be used for OPC UA operations performed by QuickOPC.

The effective application manifest is made first by composing the application manifest information from several sources, and then by resolving certain parts inside the manifest. The details of the composition and resolution processes are described further below.

Application Manifest Composition

The composition of the OPC UA application manifest is done using the following steps, in the specified order:

  1. An OPC UA automatic application manifest is determined (see further below).
  2. If the OPC UA application manifest attribute (see further below) is available, information from it overrides the information gathered so far. By default, unless you add the OPC UA application manifest attribute to your project, this step does nothing.
  3. Information from the application manifest in the application parameters (EasyUAClient.SharedParameters.EngineParameters.ApplicationParameters.ApplicationManifest ) then overrides the information gathered so far. By default, unless you set something in the application parameters explicitly from your code, this step does nothing, because the manifest information in application parameters is empty.

You can see that in the default state, only the first step (OPC UA automatic application manifest) provides the actual information; the remaining steps do nothing. If you want to modify some or all of the application provided by the automatic application manifest, you can use the OPC UA application manifest attribute to change it (this is the recommended way), or you can modify the information by writing code that changes it in the application parameters.

The reason why using the OPC UA application manifest attribute is preferred over setting the parameters from the code is that in many cases, application manifest information is needed outside of the application itself. For example, it might be needed for external administration tools. Such tools are able to read the OPC UA application manifest attribute from the application, but will not be able to see into the code and determine which values your application is setting to the application parameters.

The information in the OPC UA application manifest consists mostly of strings. Inthe composition process, a non-empty string in the application manifest that is being added to the composition overrides the existing information. An empty string leaves the information as it was. A string equal to "#" sets the information back to an empty string (this is rarely needed). For example, if the automatic application manifest determines the application name as "My Application", and you do not feel that this is the right name, you can set a non-empty application name in the OPC UA application manifest attribute, e.g. "Process Monitoring", and that will become the effective name.

Application Manifest Resolution

After the composed application manifest is computed using the process described above, QuickOPC resolves some information contained in it. Specifically, the special folder names that may be contained in certificate store paths (such as "LocalFolder") are resolved to absolute paths. The resolution process is important to assure that the certificate store paths do not change over time. Also, if/when the security configuration is exported from the application, it needs to be stripped off unnecessary context so that it is usable "as is", standalone.

Automatic Application Manifest

The automatic application manifest attempts to provide reasonable information, either by using some common defaults, or by gathering the data about the application itself. Specifically:

Application Manifest Attribute

Using the application manifest attribute is the preferred way to specify the OPC UA Application Manifest information, if it differs from what is provided by the automatic application manifest functionality. This method is only available in .NET applications.

The application manifest attribute is represented by the UAApplicationManifestAttribute Class. It contains properties for all information contained in the application manifest. As explained above in the "Application Manifest Composition" chapter, the application manifest attribute is evaluated after the automatic manifest attribute values are obtained. This means that you can only fill in the properties that you want to have changed from what is provided by the automatic application manifest functionality.

The application manifest attribute needs to be applied to the application assembly. The application assembly is usually the "main" assembly of you project. More precisely, it is:

Example syntax:

[assembly: UAApplicationManifest(OrganizationName="MyCompany", CountryName="US")]
<Assembly: UAApplicationManifest(OrganizationName:="MyCompany", CountryName:="US")>

Application Manifest in Application Parameters

You can also manipulate the application manifets information directly from your code, in the application parameters object. As explained above, this method is not preferred, and should only be used if you cannot use the automatic application manifest, possibly in combination with the application manifest attribute.

.NET

// This example demonstrates how to set the application name for the client certificate.

using System;
using OpcLabs.BaseLib.Instrumentation;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.Application;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples._UAApplicationManifest
{
    class ApplicationName
    {
        public static void Main1()
        {
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            // or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            // Hook static events
            EasyUAClient.LogEntry += EasyUAClientOnLogEntry;

            try
            {
                // Set the application name, which determines the subject of the client certificate.
                // Note that this only works once in each host process.
                EasyUAApplication.Instance.ApplicationParameters.ApplicationManifest.ApplicationName = 
                    "QuickOPC - CSharp example application";

                // Do something - invoke an OPC read, to trigger some loggable entries.
                var client = new EasyUAClient();
                try
                {
                    client.ReadValue(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853");
                }
                catch (UAException uaException)
                {
                    Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                }

                // The certificate will be located or created in a directory similar to:
                // C:\ProgramData\OPC Foundation\CertificateStores\MachineDefault\certs
                // and its subject will be as given by the application name.

                Console.WriteLine("Processing log entry events for 10 seconds...");
                System.Threading.Thread.Sleep(10 * 1000);

                Console.WriteLine("Finished.");
            }
            finally
            {
                // Unhook static events
                EasyUAClient.LogEntry -= EasyUAClientOnLogEntry;
            }
        }

        // Event handler for the LogEntry event.
        // Print the loggable entry containing client certificate parameters.
        private static void EasyUAClientOnLogEntry(object sender, LogEntryEventArgs logEntryEventArgs)
        {
            if (logEntryEventArgs.EventId == 161)
                Console.WriteLine(logEntryEventArgs);
        }
    }
}
# This example demonstrates how to set the application name for the client certificate.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.Application import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# Event handler for the LogEntry event.
# Print the loggable entry containing client certificate parameters.
def onLogEntry(sender, logEntryEventArgs):
    if logEntryEventArgs.EventId == 161:
        print(logEntryEventArgs)


endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer')
# or 'http://opcua.demo-this.com:51211/UA/SampleServer' (currently not supported)
# or 'https://opcua.demo-this.com:51212/UA/SampleServer/'

# Hook static events.
EasyUAClient.LogEntry += onLogEntry

try:
    # Set the application name, which determines the subject of the client certificate.
    # Note that this only works once in each host process.
    EasyUAApplication.Instance.ApplicationParameters.ApplicationManifest.ApplicationName = \
        'QuickOPC - Python (.NET) example application'

    # Do something - invoke an OPC read, to trigger some loggable entries.
    client = EasyUAClient()
    try:
        value = IEasyUAClientExtension.ReadValue(client,
                                                 endpointDescriptor,
                                                 UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'))
    except UAException as uaException:
        print('*** Failure: ' + uaException.GetBaseException().Message)

    # The certificate will be located or created in a directory similar to:
    # C:\ProgramData\OPC Foundation\CertificateStores\MachineDefault\certs
    # and its subject will be as given by the application name.

    print('Processing log entry events for 10 seconds...')
    time.sleep(10)

    print('Finished.')

finally:
    # Unhook static events.
    EasyUAClient.LogEntry -= onLogEntry
' This example demonstrates how to set the application name for the client certificate.

Imports OpcLabs.BaseLib.Instrumentation
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.Application
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace _UAApplicationManifest
    Friend Class ApplicationName
        Public Shared Sub Main1()

            Dim endpointDescriptor As UAEndpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
            ' or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            ' or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            ' Hook static events
            AddHandler EasyUAClient.LogEntry, AddressOf EasyUAClientOnLogEntry

            Try
                ' Set the application name, which determines the subject of the client certificate.
                ' Note that this only works once in each host process.
                EasyUAApplication.Instance.ApplicationParameters.ApplicationManifest.ApplicationName =
                    "QuickOPC - VBNet example application"

                ' Do something - invoke an OPC read, to trigger some loggable entries.
                Dim client = New EasyUAClient()
                Try
                    client.ReadValue(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853")
                Catch uaException As UAException
                    Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                    Exit Sub
                End Try

                ' The certificate will be located or created in a directory similar to:
                ' C:\ProgramData\OPC Foundation\CertificateStores\MachineDefault\certs
                ' and its subject will be as given by the application name.

                Console.WriteLine("Processing log entry events for 10 seconds...")
                Threading.Thread.Sleep(10 * 1000)

                Console.WriteLine("Finished.")
            Finally
                ' Unhook static events
                RemoveHandler EasyUAClient.LogEntry, AddressOf EasyUAClientOnLogEntry
            End Try

        End Sub


        ' Event handler for the LogEntry event.
        ' Print the loggable entry containing client certificate parameters.
        Private Shared Sub EasyUAClientOnLogEntry(ByVal sender As Object, ByVal logEntryEventArgs As LogEntryEventArgs)
            If (logEntryEventArgs.EventId = 161) Then
                Console.WriteLine(logEntryEventArgs)
            End If
        End Sub
    End Class
End Namespace

COM

// This example demonstrates how to set the application name for the client certificate.

type
  TClientManagementEventHandlers103 = class
    procedure OnLogEntry(
      ASender: TObject;
      sender: OleVariant;
      const eventArgs: _LogEntryEventArgs);
  end;

// Event handler for the LogEntry event.
// Print the loggable entry containing client certificate parameters.
procedure TClientManagementEventHandlers103.OnLogEntry(
  ASender: TObject;
  sender: OleVariant;
  const eventArgs: _LogEntryEventArgs);
begin
  if eventArgs.EventId = 161 then
      WriteLn(eventArgs.ToString);
end;

class procedure ApplicationName.Main;
var
  Application: TEasyUAApplication;
  Client: OpcLabs_EasyOpcUA_TLB._EasyUAClient;
  ClientManagement: TEasyUAClientManagement;
  ClientManagementEventHandlers: TClientManagementEventHandlers103;
  Value: OleVariant;
begin
  // The configuration object allows access to static behavior - here, the
  // shared LogEntry event.
  ClientManagement := TEasyUAClientManagement.Create(nil);
  ClientManagementEventHandlers := TClientManagementEventHandlers103.Create;
  ClientManagement.OnLogEntry := ClientManagementEventHandlers.OnLogEntry;
  ClientManagement.Connect;

  // Obtain the application interface.
  Application := TEasyUAApplication.Create(nil);

  try
    // Set the application name, which determines the subject of the client certificate.
    // Note that this only works once in each host process.
    Application.ApplicationParameters.ApplicationManifest.ApplicationName :=
      'QuickOPC - Delphi example application';

    // Do something - invoke an OPC read, to trigger some loggable entries.
    Client := CoEasyUAClient.Create;
    try
      Value := Client.ReadValue(
      //'http://opcua.demo-this.com:51211/UA/SampleServer',
      //'https://opcua.demo-this.com:51212/UA/SampleServer/',
      'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer',
      'nsu=http://test.org/UA/Data/ ;i=10853');
    except
      on E: EOleException do
      begin
        WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
      end;
    end;

    // The certificate will be located or created in a directory similar to:
    // C:\ProgramData\OPC Foundation\CertificateStores\MachineDefault\certs
    // and its subject will be as given by the application name.

    WriteLn('Processing log entry events for 10 seconds...');
    PumpSleep(10*1000);

    WriteLn('Finished...');
  finally
    FreeAndNil(Application);
    FreeAndNil(ClientManagement);
    FreeAndNil(ClientManagementEventHandlers);
  end;
end;
// This example demonstrates how to set the application name for the client certificate.

class ClientManagementEvents {
    // Event handler for the LogEntry event.
    // Print the loggable entry containing client certificate parameters.
    function LogEntry($Sender, $E)
    {
        if ($E->EventId == 161)
            printf("%s\n", $E);
    }
}

// The management object allows access to static behavior - here, the
// shared LogEntry event.
$ClientManagement = new COM("OpcLabs.EasyOpc.UA.EasyUAClientManagement");
$ClientManagementEvents = new ClientManagementEvents();
com_event_sink($ClientManagement, $ClientManagementEvents, "DEasyUAClientManagementEvents");

// Obtain the application interface.
$Application = new COM("OpcLabs.EasyOpc.UA.Application.EasyUAApplication");

// Set the application name, which determines the subject of the client certificate.
// Note that this only works once in each host process.
$Application->ApplicationParameters->ApplicationManifest->ApplicationName = "QuickOPC - PHP example application";

// Do something - invoke an OPC read, to trigger some loggable entries.
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");
try
{
    $value = $Client->ReadValue(
        //"http://opcua.demo-this.com:51211/UA/SampleServer", 
        "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer", 
        "nsu=http://test.org/UA/Data/ ;i=10853");
}
catch (com_exception $e)
{
    printf("*** Failure: %s\n", $e->getMessage());
}

// The certificate will be located or created in a directory similar to:
// C:\ProgramData\OPC Foundation\CertificateStores\MachineDefault\certs
// and its subject will be as given by the application name.

printf("Processing log entry events for 10 seconds...");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 10);

printf("Finished.\n");
Rem This example demonstrates how to set the application name for the client certificate.

Private Sub ApplicationName_Main_Command_Click()
    OutputText = ""
    
    ' Obtain the application interface
    Dim Application As New EasyUAApplication
        
    ' Set the application name, which determines the subject of the client certificate.
    ' Note that this only works once in each host process.
    Application.ApplicationParameters.ApplicationManifest.applicationName = "QuickOPC - VB6 example application"

    ' Do something - invoke an OPC read, to trigger some loggable entries.
    Dim client As New EasyUAClient
    On Error Resume Next
    Dim value As Variant
    value = client.ReadValue("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer", "nsu=http://test.org/UA/Data/ ;i=10853")
    If Err.Number <> 0 Then
        OutputText = OutputText & "*** Failure: " & Err.Source & ": " & Err.Description & vbCrLf
        Exit Sub
    End If
    On Error GoTo 0

    ' The certificate will be located or created in a directory similar to:
    ' C:\ProgramData\OPC Foundation\CertificateStores\MachineDefault\certs
    ' and its subject will be as given by the application name.

    OutputText = OutputText & "Processing log entry events for 10 seconds..." & vbCrLf
    Pause 10000
    
    Set Application = Nothing
    OutputText = OutputText & "Finished..." & vbCrLf
End Sub
' Event handler for the LogEntry event. It simply prints out the event.
Private Sub ClientManagement1_LogEntry(ByVal sender As Variant, ByVal eventArgs As OpcLabs_BaseLib.LogEntryEventArgs)
    If eventArgs.eventId = 161 Then
        OutputText = OutputText & eventArgs & vbCrLf
    End If
End Sub
Rem This example demonstrates how to set the application name for the client certificate.

Option Explicit

' The management object allows access to static behavior.
WScript.Echo "Obtaining the client management object..."
Dim ClientManagement: Set ClientManagement = CreateObject("OpcLabs.EasyOpc.UA.EasyUAClientManagement")
WScript.ConnectObject ClientManagement, "ClientManagement_"

WScript.Echo "Obtaining the application interface..."
Dim Application: Set Application = CreateObject("OpcLabs.EasyOpc.UA.Application.EasyUAApplication")

' Set the application name, which determines the subject of the client certificate.
' Note that this only works once in each host process.
WScript.Echo "Setting the application name..."
Application.ApplicationParameters.ApplicationManifest.ApplicationName = "QuickOPC - VBScript example application"

WScript.Echo "Creating a client object..."
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.UA.EasyUAClient")

' Do something - invoke an OPC read, to trigger some loggable entries.
WScript.Echo "Reading a value..."
On Error Resume Next
Dim value: value = Client.ReadValue("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer", "nsu=http://test.org/UA/Data/ ;i=10853")
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
    WScript.Quit
End If
On Error Goto 0

' The certificate will be located or created in a directory similar to:
' C:\Users\All Users\OPC Foundation\CertificateStores\UA Applications\certs\
' and its subject will be as given by the application name.

WScript.Echo "Processing log entry events for 10 seconds..."
WScript.Sleep 10*1000

WScript.Echo "Finished."



' Event handler for the LogEntry event.
' Print the loggable entry containing client certificate parameters.
Sub ClientManagement_LogEntry(Sender, e)
    If e.EventId = 161 Then WScript.Echo e
End Sub

 

 

See Also

Reference

Knowledge Base